/**
 * Copyright (c) 2018-2022, NXOS Development Team
 * SPDX-License-Identifier: Apache-2.0
 * 
 * Contains: thread
 * 
 * Change Logs:
 * Date           Author            Notes
 * 2022-05-15     JasonHu           Init
 */

#include <nxos/syscall.h>
#include <nxos/process.h>

NX_PRIVATE NX_ThreadAttr __defaultThreadAttr = NX_THREAD_ATTR_INIT;

NX_Solt NX_ThreadCreate(NX_ThreadAttr * attr, NX_U32 (*handler)(void *), void * arg, NX_U32 flags)
{
    NX_Solt solt = NX_SOLT_INVALID_VALUE;
    if (!attr)
    {
        attr = &__defaultThreadAttr;
    }

    NX_ErrorSet(NX_Syscall5(NX_API_ThreadCreate, attr, handler, arg, flags, &solt));
    return solt;
}

void NX_ThreadExit(NX_U32 exitCode)
{
    NX_Syscall1(NX_API_ThreadExit, exitCode);
}

NX_Error NX_ThreadSuspend(NX_Solt solt)
{
    NX_Error err;
    NX_ErrorSet((err = NX_Syscall1(NX_API_ThreadSuspend, solt)));
    return err;
}

NX_Error NX_ThreadResume(NX_Solt solt)
{
    NX_Error err;
    NX_ErrorSet((err = NX_Syscall1(NX_API_ThreadResume, solt)));
    return err;
}

NX_Error NX_ThreadWait(NX_Solt solt, NX_U32 * exitCode)
{
    NX_Error err;
    NX_ErrorSet((err = NX_Syscall2(NX_API_ThreadWait, solt, exitCode)));
    return err;
}

NX_Error NX_ThreadTerminate(NX_Solt solt, NX_U32 exitCode)
{
    NX_Error err;
    NX_ErrorSet((err = NX_Syscall2(NX_API_ThreadTerminate, solt, exitCode)));
    return err;
}

void NX_ThreadYield(void)
{
    NX_Syscall0(NX_API_ThreadYield);
}

NX_Error NX_ThreadAttrInit(NX_ThreadAttr * attr, NX_Size stackSize, NX_U32 schedPriority)
{
    if (!attr || !stackSize)
    {
        return NX_EINVAL;
    }

    attr->stackSize = stackSize;
    attr->schedPriority = schedPriority;
    return NX_EOK;
}

NX_U32 NX_ThreadGetId(NX_Solt solt)
{
    NX_U32 id = 0;
    NX_ErrorSet(NX_Syscall2(NX_API_ThreadGetId, solt, &id));
    return id;
}

NX_U32 NX_ThreadGetCurrentId(void)
{
    NX_Error err;
    NX_ErrorSet((err = NX_Syscall0(NX_API_ThreadGetCurrentId)));
    return err;
}

NX_Solt NX_ThreadGetCurrent(void)
{
    NX_Solt solt = NX_SOLT_INVALID_VALUE;

    NX_ErrorSet(NX_Syscall1(NX_API_ThreadGetCurrent, &solt));
    return solt;
}

NX_U32 NX_ThreadGetProcessId(NX_Solt solt)
{
    NX_U32 id = 0;
    NX_ErrorSet(NX_Syscall2(NX_API_ThreadGetProcessId, solt, &id));
    return id;
}
